#pragma once
namespace ctpl
{
	namespace detail
	{
		// A mutex-locked std::queue wrapper, with minor
		// modifications to the functionality of pop().
		template <typename T>
		struct atomic_queue
		{
			bool push(T&& value)
			{
				std::lock_guard<std::mutex> lock(this->mut);
				this->q.push(std::forward<T>(value));
				return true;
			}

			// If there is an item in the queue, pops the first item
			// into 'value' and returns true. Otherwise returns false.
			bool pop(T& value)
			{
				std::lock_guard<std::mutex> lock(this->mut);
				if (this->q.empty())
				{
					return false;
				}

				value = std::move(this->q.front());
				this->q.pop();
				return true;
			}

			bool empty() const
			{
				std::lock_guard<std::mutex> lock(this->mut);
				return this->q.empty();
			}

			void clear()
			{
				std::lock_guard<std::mutex> lock(this->mut);
				while (!this->q.empty())
				{
					this->q.pop();
				}
			}

		private:
			std::queue<T> q;
			std::mutex mut;
		};
	}
}
